/*
    Copyright  Louis CHEREL cherel.louis@gmail.com  
    This file is part of Agenda de l'Efrei.

    Agenda de l'Efrei is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Agenda de l'Efrei is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Agenda de l'Efrei.  If not, see <http://www.gnu.org/licenses/>.
 */

package fr.efrei.AgendaEfrei;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.view.MenuItem;
import android.webkit.WebView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.GregorianCalendar;
import java.util.regex.Pattern;

public class FileManager extends AsyncTask<Object,Boolean,String> {
            
    private MenuItem progressbar=null;
    private WebView webview;
    private String promo;
    private String day;
    private String weekIndice;
    private String page;
    private Context parent;
    private boolean mode;
    private boolean isRefresh;
    private Toast toast;

    /*
     * on récupère les infos du Thread principal
     */
    FileManager(String mPromo,String mDay,String mWeekIndice,boolean mMode,boolean mIsRefresh,Context mParent){
        promo = mPromo;
        day = mDay;
        weekIndice = mWeekIndice;
        page = "http://edt.bde.assos.efrei.fr/?s="+weekIndice+"&d="+day+"&p="+promo;
        parent = mParent;
        mode = mMode;
        isRefresh = mIsRefresh;
    }

    @Override
    protected String doInBackground(Object... list) {

        // Le "champ de retour", fil conducteur de cette classe
        String returnField="";
        
        if(mode==true) {
            try {
                // on récupère la webview
                webview = (WebView) list[0];
                progressbar = (MenuItem) list[1];
                if(isRefresh){
                    toast = (Toast) list[2];
                }
                    
                publishProgress(false);
                MainActivity.setIsFileManagerLaunched(true);
                // nom du fichier
                String filename = "p"+promo+"_d"+day+"_w"+weekIndice;

                File file = new File(parent.getFilesDir(), filename);
                if (file.exists() && !isRefresh) {
                    returnField = getCacheFiles(filename);
                }
                else {
                    // on récupère la page d'internet
                    returnField = getUrlContent(page,filename);
                }

            }catch(Exception e){
                returnField="echec [3]"+e.toString();
            }
            return returnField;
        }
        else
        {
            int file_weekIndice;
            if(Integer.parseInt(weekIndice)>0)
            {
                
                file_weekIndice=Integer.parseInt(weekIndice);
            }
            else{
                file_weekIndice=52;
            }
            int file_weekIndice2;
            //String filenames_test="";
            File file = new File(parent.getFilesDir(),"");
            File[] files = file.listFiles(new DirFilter("_w"));
            GregorianCalendar calendar = new GregorianCalendar();
            int file_day;
            file_day = (calendar.get(GregorianCalendar.DAY_OF_WEEK)==GregorianCalendar.SUNDAY)?7:Integer.parseInt(day);
            
            int file_day2;
            int files_length = files.length;
            Pattern pattern1 = Pattern.compile("(.*)_d((?:-){0,1}[0-9])_w([0-9]{1,2})", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
            for(int i=0;i<files_length;i++)
            {
                try{
                    file_day2 = Integer.parseInt(pattern1.matcher(files[i].getName()).replaceFirst("$2"));
                    file_weekIndice2= Integer.parseInt(pattern1.matcher(files[i].getName()).replaceFirst("$3"));
                    //filenames_test+="[ "+file_day2+"/"+file_day+" "+file_weekIndice2+"/"+file_weekIndice+" ]   ";
                    if(file_day > file_day2 && (file_day2>=0 || file_weekIndice2 < file_weekIndice) && file_weekIndice2 <= file_weekIndice){
                        files[i].delete();
                        //filenames_test+=" "+files[i].getName();
                    }
                }catch(Exception e){
                    returnField="echec [20]"+e.toString();
                }
            }
            //return filenames_test;
            return "";
        }
        
    }

    @Override
    protected void onPostExecute(String returnField) {
        // on charge la page sur la webview uniquement si on est en mode récup et non en mode suppr
        if(mode)
        {
            webview.getSettings().setDefaultTextEncodingName("utf-8");
            webview.loadDataWithBaseURL("",returnField, "text/html", "utf-8","");
            //webview.setInitialScale(8);
            MainActivity.setIsFileManagerLaunched(false);
            publishProgress(true);
            
        }
    }

    @Override
    protected void onProgressUpdate(Boolean...b) {
        if(progressbar!=null) {
            if(!b[0]){
                progressbar.setActionView(R.layout.progressbar);
                progressbar.expandActionView();
            }
            else{
                progressbar.collapseActionView();
                progressbar.setActionView(null);
                
                if(isRefresh) {
                    toast.show();
                }
            }
        }
    }

    private String getCacheFiles(String filename) {
        String returnField;
        char[] buffer = new char[100000];
        try{
            FileReader in = new FileReader(parent.getFilesDir()+"/"+filename);
            in.read(buffer,0,99990);
            returnField = new String(buffer);
        } catch(Exception e) {
            returnField="getCacheFiles [0] "+e.toString();
        }
        return returnField;
    }

    private String getUrlContent(String page,String filename){

        // toujours le même fil conducteur
        // on instancie le buffer dans lequel on va récupérer la page
        String returnField;
        char[] buffer = new char[100000];
        
        // on checke la connectivité réseau avant d'essayer de télécharger
        
        if(isNetworkAvailable())
        {
            try{
                // on indique la bonne URL
                URL page_data = new URL(page);

                try {
                    // on télécharge la page
                    InputStream in = page_data.openConnection().getInputStream();
                    InputStreamReader html_content = new InputStreamReader(in);

                    // tant que le contenu n'est pas prêt... on met tout dans le buffer
                    // puis on retourne le buffer au fil conducteur
                    while(!html_content.ready()) {}
                    html_content.read(buffer,0,99990);
                    in.close();
                    returnField = new String(buffer);

                    // correction du document HTML qui est immonde.
                    Pattern pattern1 = Pattern.compile("<meta(.*)utf-8\">", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
                    Pattern pattern1bis = Pattern.compile("<meta(.*)root\">", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
                    Pattern pattern1ter = Pattern.compile("<meta(.*)ieux\">", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
                    Pattern pattern2 = Pattern.compile("([A-Z]{2,20})=([[A-Z][0-9]]{1,20})", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
                    Pattern pattern3 = Pattern.compile("<input(.*)\"Afficher\">", Pattern.DOTALL|Pattern.COMMENTS);
                    Pattern pattern4 = Pattern.compile("<form(.*)form>", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
                    Pattern pattern5 = Pattern.compile("</TABLE(.*)body", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
                    returnField = pattern1.matcher(returnField).replaceFirst("<meta$1utf-8\"/><meta name=\"viewport\" content=\"target-densitydpi=device-dpi\"/>");//target-densitydpi=device-dpi,minimum-scale=0.01, user-scalable=yes\" />");
                    returnField = pattern1bis.matcher(returnField).replaceFirst("");
                    returnField = pattern1ter.matcher(returnField).replaceFirst("");
                    returnField = pattern2.matcher(returnField).replaceAll("$1=\"$2\"");
                    returnField = pattern3.matcher(returnField).replaceFirst("");
                    returnField = pattern4.matcher(returnField).replaceFirst("");
                    returnField = pattern5.matcher(returnField).replaceFirst("</TABLE></body");


                    //on sauvegarde la page en local pour réutilisation
                    saveFile(filename,returnField);
                } catch(Exception e) {
                    returnField="InputStream [1] "+e.toString();
                }

            } catch (Exception e) {
                returnField="getURL [2] "+e.toString();
            }
        }
        else{
            returnField = "Cannot Retrieve Data: No internet connection";
        }

        return returnField;
    }

    public boolean isNetworkAvailable(){
        boolean isAvailable;
        ConnectivityManager connectivityMgr =(ConnectivityManager) parent.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityMgr.getActiveNetworkInfo();
        if(networkInfo!=null && networkInfo.isAvailable()){
            isAvailable = true;
        }
        else {
            isAvailable = false;
        }
        return isAvailable;
    }

    private boolean saveFile(String filename,String content){ // throws FileNotFoundException,IOException {
        try{
            FileOutputStream oS;
            File test = new File(parent.getFilesDir(),filename);
            if(isRefresh && test.exists()){
                test.delete();
            }
            boolean fileCreated = test.createNewFile();
            oS = parent.openFileOutput(filename, Context.MODE_PRIVATE);
            oS.write(content.getBytes());
            oS.close();
        return fileCreated;
        }catch(Exception e){}
        return false;
    }

}

class DirFilter implements FilenameFilter {
    String filename;
    DirFilter(String filename) { this.filename = filename; }

    public boolean accept(File dir, String name) {
        // Information du chemin de répertoire :
        String f = new File(name).getName();
        return f.indexOf(filename) != -1;
    }
}
